﻿using PickGold.Base.OCR.QRCode.Positioning;
using System.Collections;

namespace PickGold.Base.OCR.QRCode
{
	public abstract class BitMatrix
	{
		public abstract bool this[int i, int j] { get; set; }
		/// <summary>
		/// default 21
		/// </summary>
		public abstract int Width { get; }
		public abstract int Height { get; }
		public abstract bool[,] InternalArray { get; }

		internal MatrixSize Size
		{
			get { return new MatrixSize(Width, Height); }
		}

		internal bool this[MatrixPoint point]
		{
			get { return this[point.X, point.Y]; }
			set { this[point.X, point.Y] = value; }
		}

		internal void CopyTo(TriStateMatrix target, MatrixRectangle sourceArea, MatrixPoint targetPoint, MatrixStatus mstatus)
		{
			for (int j = 0; j < sourceArea.Size.Height; j++)
			{
				for (int i = 0; i < sourceArea.Size.Width; i++)
				{
					bool value = this[sourceArea.Location.X + i, sourceArea.Location.Y + j];
					target[targetPoint.X + i, targetPoint.Y + j, mstatus] = value;
				}
			}
		}

		internal void CopyTo(TriStateMatrix target, MatrixPoint targetPoint, MatrixStatus mstatus)
		{
			CopyTo(target, new MatrixRectangle(new MatrixPoint(0, 0), new MatrixSize(Width, Height)), targetPoint, mstatus);
		}

		public BitArray FillArray(BitArray target)
		{
			var w = this.Width;
			var h = this.Height;
			var pre = int.MinValue;
			if(target == null)
				target = new BitArray(w * h);// new SquareBitMatrix(matrix.Width);
			for (var iy = 0; iy < h; iy++)
			{
				for (var ix = 0; ix < w; ix++)
				{
					if (this[ix, iy])
					{
						if (pre == int.MinValue)//Set start point if preX == -1
							pre = ix;
						if (ix == w - 1)//If this is last module in that row. Draw rectangle
						{
							var ii = ix - pre + 1;
							for (var i = 0; i < ii; i++)
								target[iy * w + pre + i] = true;// bs[pre + i, iy] = true;
							pre = int.MinValue;
						}
					}
					else if (pre != int.MinValue)
					{
						//Here will be first light module after sequence of dark module.
						//Draw previews sequence of dark Module
						var ii = ix - pre;
						for (var i = 0; i < ii; i++)
							target[iy * w + pre + i] = true;// bs[pre + i, iy] = true;
						pre = int.MinValue;
					}
				}
			}
			return target;
		}

		public BitArray FillArray()
		{
			return FillArray(null);
		}
	}
}
